package com.kele.controller;

import com.kele.domain.User;
import com.kele.service.UserService;
import com.kele.utils.ResponseData;
import com.sun.mail.util.MailSSLSocketFactory;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpSession;
import java.util.Properties;

/**
 * @author 赵奥林
 * @date 2021年05月29日 15:09
 * @Description 邮箱验证  登陆注册、找回密码
 */

@RestController
@RequestMapping("/email")
@Api(value = "邮箱验证", tags = {"邮箱验证码验证操作"})
public class emailController {

    static String stringBuilder = "";

    @Resource
    private UserService userService;

    /**
     * 发送邮箱验证码操作
     *
     * @param qqEmail
     * @param session
     * @return
     * @throws Exception
     * @author 赵奥林
     */
    @RequestMapping(value = "/sendEmail", method = RequestMethod.POST)
    @ApiOperation(value = "发送邮箱验证码", notes = "发送邮箱验证码，存到session中")
    public ResponseData sendEmail(String qqEmail,
                                  @ApiIgnore HttpSession session) throws Exception {
        if (!qqEmail.equals("")) {
            //将验证码存到session中，并设置session有效期为60s
            session.setAttribute(stringBuilder, emailController.mailUtil(qqEmail));
            session.setMaxInactiveInterval(60);
            return ResponseData.success("验证码发送成功", stringBuilder);
        } else {
            return ResponseData.fail("邮箱不能为空");
        }

    }


    /**
     * 使用邮箱验证注册账号
     *
     * @param qqEmail
     * @param password
     * @param rePassword
     * @return 截取邮箱字串中@前的字符串为账号 并验证验证码是否正确
     * @author 赵奥林
     */
    @RequestMapping(value = "/emailRegister", method = RequestMethod.POST)
    @ApiOperation(value = "邮箱验证注册", notes = "通过邮箱验证注册")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "qqEmail", value = "用户邮箱", required = true),
            @ApiImplicitParam(name = "password", value = "密码", required = true),
            @ApiImplicitParam(name = "rePassword", value = "重复密码", required = true),
            @ApiImplicitParam(name = "emailCode", value = "验证码", required = true)
    })
    public ResponseData emailRegister(String qqEmail,
                                      String password,
                                      String rePassword,
                                      String emailCode,
                                      @ApiIgnore HttpSession session,
                                      @ApiIgnore ModelAndView modelAndView) throws Exception {
        String error = "";
        session.getAttribute(stringBuilder);
        if (emailCode.equals(stringBuilder)) {
            String account = qqEmail.substring(0, qqEmail.indexOf("@"));
            if (userService.queryByAccount(account) == null) {
                if (password.equals(rePassword)) {
                    User user = new User();
                    user.setAccount(account);
                    user.setPassword(password);
                    user.setEmail(qqEmail);
                    userService.insertUser(user);
                    return ResponseData.success("注册成功", user);
                } else {
                    error = "两次密码输入不一致";
                }
            } else {
                error = "用户名不可用";
            }
        } else {
            error = "验证码错误";
        }
        modelAndView.addObject("error", error);
        return ResponseData.fail(error);
    }

    /**
     * 邮箱验证码登录
     * @author 赵奥林
     * @param qqEmail
     * @param emailCode
     * @param session
     * @param modelAndView
     * @return 邮箱验证码登录，登陆后和账号登陆一样
     */
    @RequestMapping(value = "/emailLogin", method = RequestMethod.POST)
    @ApiOperation(value = "邮箱验证登录", notes = "通过邮箱验证码登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "qqEmail", value = "用户邮箱", required = true),
            @ApiImplicitParam(name = "emailCode", value = "验证码", required = true)
    })
    public ResponseData emailLogin(String qqEmail,
                                   String emailCode,
                                   @ApiIgnore HttpSession session,
                                   @ApiIgnore ModelAndView modelAndView) throws Exception {
        String error = "";
        session.getAttribute(stringBuilder);
        if (emailCode.equals(stringBuilder)) {
            String account = qqEmail.substring(0, qqEmail.indexOf("@"));
            String password = userService.queryPasswordByAccount(account);
            User user = userService.loginUser(account, password);
            if (user != null) {
                session.setAttribute("User", user);
                return ResponseData.success("登陆成功", user);
            } else {
                error = "用户名不存在";
            }
        } else {
            error = "验证码错误";
        }
        modelAndView.addObject("error", error);
        return ResponseData.fail(error);
    }


    /**
     * 通过邮箱验证码重置密码
     * @author 赵奥林
     * @param qqEmail
     * @param newPassword
     * @param rePassword
     * @param emailCode
     * @param session
     * @return
     */
    @RequestMapping(value = "/findPassword", method = RequestMethod.POST)
    @ApiOperation(value = "重置密码", notes = "通过邮箱验证来更改密码")
    public ResponseData findPassword(String qqEmail,
                                     String newPassword,
                                     String rePassword,
                                     String emailCode,
                                     @ApiIgnore HttpSession session) {
        String error = "";
        session.getAttribute(stringBuilder);
        if (newPassword.equals(rePassword)) {
            if (emailCode.equals(stringBuilder)) {
                User user = userService.queryUserByEmail(qqEmail);
                if (user != null) {
                    userService.updatePasswordByEmail(qqEmail, newPassword);
                    error = "重置密码成功";
                } else {
                    error = "重置密码失败";
                }
            } else {
                error = "验证码错误";
            }
        } else {
            error = "两次输入密码不一致";
        }
        return ResponseData.success(error);
    }


    /**
     * 配置邮箱服务
     * @author 赵奥林
     * @param toEmail
     * @throws Exception
     * @description 邮箱设置
     */
    public static ResponseData mailUtil(String toEmail) throws Exception {
        Properties prop = new Properties();
        // 开启debug调试，以便在控制台查看
        prop.setProperty("mail.debug", "true");
        // 设置邮件服务器主机名
        prop.setProperty("mail.host", "smtp.qq.com");
        // 发送服务器需要身份验证
        prop.setProperty("mail.smtp.auth", "true");
        // 发送邮件协议名称
        prop.setProperty("mail.transport.protocol", "smtp");
        // 开启SSL加密，否则会失败
        MailSSLSocketFactory sf = new MailSSLSocketFactory();
        sf.setTrustAllHosts(true);
        prop.put("mail.smtp.ssl.enable", "true");
        prop.put("mail.smtp.ssl.socketFactory", sf);
        // 创建session
        Session session = Session.getInstance(prop);
        // 通过session得到transport对象
        Transport ts = session.getTransport();
        // 连接邮件服务器：邮箱类型，帐号，POP3/SMTP协议授权码 163使用：smtp.163.com
        ts.connect("smtp.qq.com", "3189137314", "lfqymuctjywrdcef");
        // 创建邮件
        Message message = createSimpleMail(session, toEmail);
        // 发送邮件
        ts.sendMessage(message, message.getAllRecipients());

        ts.close();
        return ResponseData.success("验证码发送成功");
    }

    /**
     * @author 赵奥林
     * @Method: createSimpleMail
     * @Description: 创建一封只包含文本以及随机验证码的邮件
     */
    public static MimeMessage createSimpleMail(Session session, String toEmail) throws Exception {
        //重置验证码
        stringBuilder = "";
        //  获取6为随机验证码
        String[] letters = new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
        //随机生成六位验证码
        for (int i = 0; i < 6; i++) {
            stringBuilder = stringBuilder + letters[(int) Math.floor(Math.random() * letters.length)];
        }
        // 创建邮件对象
        MimeMessage message = new MimeMessage(session);
        // 指明邮件的发件人
        message.setFrom(new InternetAddress("3189137314@qq.com"));
        // 指明邮件的收件人
        message.setRecipient(Message.RecipientType.TO, new InternetAddress(toEmail));
        // 邮件的标题
        message.setSubject("可乐验证");
        // 邮件的文本内容
        message.setContent("欢迎您使用【可乐】,您的验证码为(一分钟有效):" + stringBuilder + ",请勿回复此邮件。", "text/html;charset=UTF-8");
        // 返回创建好的邮件对象
        return message;
    }


}
